
from threading import *
import copy

class Future:

    def __init__(self, func, *param):
        # constructor
        self.__done = 0
        self.__result = None
        self.__status = 'working'

        self.__C = Condition(  ) # Notify on this Condition when result is ready

        # Run the actual function in a separate thread
        self.__T = Thread(target=self.Wrapper, args=(func, param))
        self.__T.setName("FutureThread")
        self.__T.start(  )

    def __repr__(self):
        return '<Future at '+hex(id(self))+':'+self.__status+'>'

    def __call__(self):
        self.__C.acquire(  )
        while self.__done==0:
            self.__C.wait(  )
        self.__C.release(  )
        # Deepcopy __result to prevent accidental tampering with it
        result = copy.deepcopy(self.__result)
        return result

    def isDone(self):
        return self.__done

    def Wrapper(self, func, param):
        # Run the actual function and housekeep around it
        self.__C.acquire(  )
        self.__result = func(*param)
        self.__done=1
        self.__status=`self.__result`
        self.__C.notify(  )
        self.__C.release(  )

